// Mail message extractor
// Extract messages from inbox files such as Thunderbird or usenet
// by DreamVB 20:34 03/10/2016
// Version 1.0

#include <iostream>
#include <Windows.h>
#include <algorithm>
#include <fstream>
#include <sstream>
#include <string>

using namespace std;
using std::cout;
using std::endl;

bool DirExists(string path){
	wstring ws(path.begin(), path.end());
	//Check if a file was found.
	if (GetFileAttributes(ws.c_str()) != FILE_ATTRIBUTE_DIRECTORY){
		return false;
	}
	return true;
}

string Dec2Str(int value){
	ostringstream os;
	os << value;
	return os.str();
}

string UnixToDos(string src){
	int i = 0;
	string buffer = "";

	while (i < src.length()){
		if (src[i] == '\n'){
			//Check for \r
			if (src[i] != '\r'){
				buffer += "\r\n";
			}
			else{
				buffer += "\n";
			}
		}
		else{
			buffer += src[i];
		}
		i++;
	}
	return buffer;
}

int main(int argc, char *argv[]){

	fstream fs;
	fstream fout;
	string StrLine = "";
	string PrevStr = "";
	string InBoxFile = "";
	string sOut = "";
	string sOutFile = "";
	string sMessage = "";
	int x = 0;

	if (argc < 2){
		cout << "Usage: " << argv[0] << " <InboxFile> <OutputFolder>" << endl;
		exit(1);
	}

	//Get inbox filename.
	InBoxFile = argv[1];
	sOut = argv[2];

	//Check if output folder is here.
	if (!DirExists(sOut)){
		cout << "Directory Not Found:" << endl;
		cout << sOut.c_str() << endl;
		exit(1);
	}

	fs.open(InBoxFile.c_str(), ios::in | ios::binary);

	//Check if file is open.
	if (!fs.good()){
		cout << "Cannot Read Input File:" << endl;
		cout << InBoxFile.c_str() << endl;
		exit(1);
	}

	//Read the inbox file and extract the messages.
	while (getline(fs,StrLine)){
		//Check for line length
		if (StrLine.length() > 0){
			//Check for the string From this is were the message begins
			if (StrLine.substr(0, 5) == "From "){
				cout << "Extracting: " << StrLine.c_str() << endl;
				//If StrLine not equal Prev String then output message data
				if (StrLine != PrevStr){
					//Check the length of the message.
					if (sMessage.length() > 0){
						//Set output file
						sOutFile = sOut + "message_" + Dec2Str(x) + ".txt";
						//Open the file for output
						fout.open(sOutFile, ios::out | ios::binary);
						//Check that the file was open if not exit.
						if (!fout.good()){
							cout << "Cannot Create Output File: " << endl;
							cout << sOutFile.c_str() << endl;
						}
						sMessage = UnixToDos(sMessage);
						//Write data to the file.
						fout.write(sMessage.c_str(), sMessage.length());
						//Close file
						fout.close();
						//Clear message.
					}
				}
				//INC counter
				x++;
				sMessage.clear();
			}
			//Build the message.
			sMessage += StrLine + "\n";
			//Store prev string
			PrevStr = StrLine;
		}
	}
	
	//Output last one
	sMessage = UnixToDos(sMessage);
	sOutFile = sOut + "message_" + Dec2Str(x) + ".txt";
	fout.open(sOutFile, ios::out | ios::binary);
	fout.write(sMessage.c_str(), sMessage.length());
	//Close file
	fs.close();

	//Display messages found.
	cout << "Finished " << x << " messages extracted." << endl;

	//Clear up.
	sMessage.clear();
	StrLine.clear();

	return 0;
}